use egui::Id;
use thunderdome::{Arena, Index};
use QcCore::resources::ResourceManager;
use QcTools::sync::OnceCell;
use QcUI::core::context::UiContext;

use crate::managers::resource_manager::ResourceManagerExt;
use crate::{
    components::{
        dock::DockView,
        nestable::{Command, HierarchicalDragAndDrop, ItemTrait},
    },
    core::{context::Context, message::EditorMessage},
};
use std::{
    path::PathBuf,
    sync::{mpsc::Sender, Arc, RwLock},
};

use super::{ResFile, ResItem};

#[derive(Debug)]
pub struct ResPanel {
    context: Arc<Context>,
    list: HierarchicalDragAndDrop<ResItem>,
    editor_sender: Sender<EditorMessage>,
}

impl DockView for ResPanel {
    fn render(&mut self, ctx: &mut UiContext, show_tab: bool) {
        let resource_manager = self.context.resource_manager.clone();
        egui::Frame::none()
            .outer_margin(egui::Margin::same(8.))
            .show(ctx.ui, |ui| {
                egui::ScrollArea::new([false, true]).show(ui, |ui| {
                    ui.set_width(ui.available_width());
                    self.list.ui(ui, |command| {
                        match command {
                            Command::MoveItem {
                                moved_item_id,
                                target_container_id,
                                target_position_index,
                            } => {}
                            Command::SetSelectedItem(item_id) => {
                                if let Some(item) = item_id {
                                    if let Some(file) = resource_manager.get_file(item.get_id()) {
                                        if file.file_name.contains(".scene") {
                                            self.editor_sender
                                                .send(EditorMessage::OpenScene(file.clone()))
                                                .unwrap();
                                        }
                                    }
                                }
                            }
                            _ => {}
                        };
                        true
                    });
                });
            });
    }
}

impl ResPanel {
    pub fn new(context: Arc<Context>, editor_sender: Sender<EditorMessage>) -> Self {
        let mut list = HierarchicalDragAndDrop::new(context.clone());

        {
            let root_id = list.root_id;
            let context = context.clone();
            let config = context.project_config.try_read().unwrap();
            if let Some(config) = config.as_ref() {
                let path = config.get_path();

                let resource_manager = context.resource_manager.clone();
                resource_manager.clear();
                Self::build_res_item(&mut list, resource_manager, path, root_id);
            }
        }

        Self {
            context,
            list,
            editor_sender,
        }
    }

    pub fn build_res_item(
        list: &mut HierarchicalDragAndDrop<ResItem>,
        files: Arc<ResourceManager>,
        path: &PathBuf,
        item_id: ResItem,
    ) {
        let path_str = path.to_str().unwrap();
        if path_str.contains("build") || path_str.contains("node_modules") {
            return;
        }

        let file_name = path
            .file_name()
            .unwrap()
            .to_os_string()
            .into_string()
            .unwrap();
        if path.is_dir() {
            let file = ResFile::new(path.clone(), file_name);
            let index = files.add_file(file);

            let item_id = list.add_container(item_id, index);
            for entry in path.read_dir().unwrap() {
                if let Ok(entry) = entry {
                    let entry_path = entry.path();

                    Self::build_res_item(list, files.clone(), &entry_path, item_id);
                }
            }
        } else {
            let file = ResFile::new(path.clone(), file_name);
            let name = file.file_name.clone();
            let index = files.add_file(file);

            list.add_leaf(item_id, &name, index);
        }
    }
}
